"""
Created on 16 Dec 2020
@fake_author:JemusD
"""
import numpy as np
from os import listdir
# sorted 里面给字典选择key还是value排序用到的一个包
import operator


# 将图片矩阵转成行向量
def image2vector(filename):
    fr = open(filename)
    returnVect = np.zeros((1,1024))

    for i in range(32):
        # i从0开始
        lineStr = fr.readline()
        for j in range(32):
            returnVect[0, 32*i+j] = int(lineStr[j])
    return returnVect


def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    # 函数tile(array, y) y表示array重复方式,y=(1,5) 表示一行5个array. y=(5,1) 表示5行每行一个array.
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat**2
    # sum(0) col列相加，sum(1) row行相加
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    # ^以上即为 sqrt( (x1-x2)^2 + (y1-y2)^2 )
    # argsort() 返回数组中从小到大的索引
    sortedDistIndicies = distances.argsort()
    # print(sortedDistIndicies)

    classCount = {}
    # 一个给标签计数的循环
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        # dict.get(key, default=None) if haven't this key, return default 
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    # dict.items() 返回一个可遍历的列表，里面是元组
    # key = operator.itemgetter(0) 表示按'键'进行排序
    # key = operator.itemgetter(1) 表示按'值'进行排序
    # 默认为从升序排序，reverse = True表示为降序排列
    sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
    return sortedClassCount[0][0]


"""
instructions: 手写识别函数
    hwLabels - 手写数字标签
    trainingFilesList - 打开目录后，该文件夹下的文件列表
    os.listdir() - 列出给定目录的文件名
Parameters: 
    None
Returns:
    None
Modify:
    2020-12-17
"""
def handWritingClassTest():
    hwLabels = []
    trainingFilesList = listdir('trainingDatas')
    m = len(trainingFilesList)
    trainingMat = np.zeros((m,1024))
    for i in range(m):
        fileNameStr = trainingFilesList[i]
        # x = 'abcdef' x[0] -> 'a'
        classNumber = int(fileNameStr.split('_')[0])
        hwLabels.append(classNumber)
        # 以上为labels提取，从文件名字提取其right answer: 5_78.txt -> 5
        trainingMat[i,:] = image2vector('trainingDatas/%s' % (fileNameStr))
        
       
    testFileList = listdir('testDatas')
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        classNumber = int(fileNameStr.split('_')[0])
        vectorUnderTest = image2vector('testDatas/%s' % (fileNameStr))
        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
        # print("the result of classifier:%d\t the true value is:%d" % (classifierResult, classNumber))
        if(classifierResult != classNumber):
            errorCount += 1.0
    print("the k is: 3")    
    print("the total error:%d\nerror ratio is:%f%%" % (errorCount, errorCount/mTest * 100))


def main():
    handWritingClassTest()

if __name__ == '__main__':
    main()
# dingpengda come from china
